package com.clarence.dada.modular.system.user.service.impl;


import cn.hutool.core.codec.Base64;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.clarence.dada.core.redis.RedisOperatorApi;
import com.clarence.dada.core.enums.ErrorEnum;
import com.clarence.dada.core.exception.BusException;
import com.clarence.dada.core.util.DragCaptchaImageUtil;
import com.clarence.dada.modular.system.user.entity.resp.DragCaptchaImageResp;
import com.clarence.dada.modular.system.user.service.DragCaptchaService;
import lombok.extern.slf4j.Slf4j;

import java.io.ByteArrayInputStream;
import java.io.IOException;

/**
 * 拖拽验证码实现
 *
 * @author GD
 * @since 2021/7/5 11:34
 */
@Slf4j
public class DragCaptchaServiceImpl implements DragCaptchaService {

    private final RedisOperatorApi<String> redisOperatorApi;

    public DragCaptchaServiceImpl(RedisOperatorApi<String> redisOperatorApi) {
        this.redisOperatorApi = redisOperatorApi;
    }

    public DragCaptchaImageResp createCaptcha() {
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(Base64.decode(DragCaptchaImageUtil.IMAGE_BASE64));
        try (byteArrayInputStream){
            DragCaptchaImageResp dragCaptchaImageResp = DragCaptchaImageUtil.getVerifyImage(byteArrayInputStream);

            // 缓存x轴坐标
            String verKey = IdUtil.simpleUUID();
            Integer verValue = dragCaptchaImageResp.getLocationX();
            redisOperatorApi.put(verKey, verValue.toString());

            // 清空x轴坐标
            dragCaptchaImageResp.setKey(verKey);

            return dragCaptchaImageResp;
        } catch (IOException e) {
            throw new BusException(ErrorEnum.CAPTCHA_ERROR);
        }
    }

    public boolean validateCaptcha(String verKey, Integer verScope) {
        if (StrUtil.isEmpty(verKey)) {
            return false;
        }
        if (verScope == null) {
            return false;
        }

        // 获取缓存中正确的locationX的值
        String locationStringX = redisOperatorApi.get(verKey);
        if (StrUtil.isEmpty(locationStringX)) {
            throw new BusException(ErrorEnum.CAPTCHA_INVALID_ERROR);
        }

        // 获取缓存中存储的范围
        Integer locationX = Convert.toInt(locationStringX);
        int beginScope = locationX - 5;
        int endScope = locationX + 5;

        // 每次验证不管成功和失败都剔除掉key
        redisOperatorApi.remove(verKey);

        // 验证缓存中的范围值
        return verScope >= beginScope && verScope <= endScope;
    }

}
